package cs236369.hw5.db.beans;

import java.util.Date;
import java.util.List;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.ManyToOne;
import javax.persistence.PrePersist;
import javax.persistence.PreUpdate;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;

import org.hibernate.annotations.Cascade;
import org.hibernate.annotations.CascadeType;

import cs236369.hw5.db.DbBean;

@Entity
@Table(name = "EVENTS")
public class DbEvent implements DbBean
{

	@Id
	@Column(name = "ID", unique = true, nullable = false)
	@GeneratedValue(strategy = GenerationType.IDENTITY)
	private Long id;

	@ManyToOne(fetch = FetchType.LAZY)
	@JoinColumn(name = "MSG_ID", nullable = false, insertable = true, updatable = true)
	@Cascade(CascadeType.SAVE_UPDATE)
	private DbMessage msg;

	@Temporal(TemporalType.TIMESTAMP)
	@Column(name = "EVENT_DATE", nullable = false)
	private Date date = new Date();

	// if there isn't capacity limit, it will be null.
	@Column(name = "CAPACITY", unique = false, nullable = true)
	private Integer capacity;
	
	@Column(name = "REGISTERED", unique = false, nullable = false, columnDefinition="int4 default 0")
	private Integer registered = 0;

	@ManyToMany(fetch = FetchType.LAZY, cascade=javax.persistence.CascadeType.PERSIST)
	@JoinTable(name = "USER_EVENTS",  joinColumns = { 
			@JoinColumn(name = "EVENT_ID", nullable = false, updatable = false) }, 
			inverseJoinColumns = { @JoinColumn(name = "USER_NAME", nullable = false, updatable = false) })
	
	private List<DbUser> users;
	
	public DbEvent(DbMessage msg, Integer capacity, Date date)
	{
		this.msg = msg;
		this.capacity = capacity;
		this.date = date;
	}
	public DbEvent()
	{
		// empty ctor for bean.

	}

	public Long getId()
	{
		return id;
	}

	public void setId(Long id)
	{
		this.id = id;
	}

	public DbMessage getMsg()
	{
		return msg;
	}

	public void setMsg(DbMessage msg)
	{
		this.msg = msg;
	}

	@PreUpdate
	@PrePersist
	protected void onDate()
	{
		this.date = new Date();
	}

	public Date getDate()
	{
		return date;
	}

	public void setDate(Date date)
	{
		this.date = date;
	}

	public Integer getCapacity()
	{
		return capacity;
	}

	public void setCapacity(Integer capacity)
	{
		this.capacity = capacity;
	}
	public Integer getRegistered()
    {
	    return registered;
    }
	public void setRegistered(Integer registered)
    {
	    this.registered = registered;
    }
	/**
	 * use {@link #registerUser(DbUser)}  / {@link #unRegisterUser(DbUser)} 
	 * @return
	 */
	public List<DbUser> getUsers()
    {
	    return users;
    }
	
	/**
	 * use {@link #registerUser(DbUser)}  / {@link #unRegisterUser(DbUser)} 
	 * @return
	 */
	public void setUsers(List<DbUser> users)
    {
	    this.users = users;
    }
	
	public void registerUser(String user)
	{
		getUsers().add(new DbUser(user));
		++capacity;
	}
	
	public void unRegisterUser(String user)
	{
		int n = getUsers().size();
		for (int i=0; i< n; ++i)
		{
			if (getUsers().get(i).getUsername().equals(user))
			{
				getUsers().remove(i);
				--capacity;
				return;
			}
		}
		
		
	}
}
